//
//  NSString+PLValidate.m
//  PlatformCommon
//
//  Created by KimmanYip on 2017/9/17.
//

#import "NSString+PLValidate.h"

@implementation NSString(PLValidate)


#pragma mark - Instance Method

/**
 *  是否符合给定的正则表达式
 *
 *  @param expression 正则表达式
 *
 *  @return 是否符合
 */
- (BOOL)pl_isMatchToRegular:(NSString *)expression {
    NSPredicate *regex = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", expression];
    return [regex evaluateWithObject:self];
}

/**
 *  是否符合所有给定的正则表达式
 *
 *  @param expressions 所有给定的表达式数组
 *
 *  @return 是否都符合
 */
- (BOOL)pl_isMatchToRegulars:(NSArray *)expressions {
    if (expressions && [expressions isKindOfClass:[NSArray class]]) {
        for (NSString *expression in expressions) {
            if (![self pl_isMatchToRegular:expression]) {
                return  NO;
            }
        }
    }
    return YES;
}

/**
 *  检验邮箱格式
 *
 *  @return 格式是否正确
 */
- (BOOL)pl_isEmail {
    static NSString * regex = @"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$";
    NSPredicate * pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:self];
}

/**
 *  非严格校验手机号码格式, 1-11位纯数字, 以1开头
 *
 *  @return 格式是否正确
 */
- (BOOL)pl_isMobileNumber {
    static NSString *regex = @"^1[0-9]{10}$";
    NSPredicate * pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:self];
}

/**
 *  校验座机号，7-12位纯数字
 *
 *  @return 格式是否正式
 */
- (BOOL)pl_isLandLineNumber {
    static NSString *regex = @"^[0-9]{7,12}$";
    NSPredicate * pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:self];
}

/**
 *  判断字符串是否只包含空格或换行符
 *
 *  @return 是否只包含空格或换行符
 */
- (BOOL)pl_isWhitespaceAndNewlines {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0;
}

/**
 *  判断字符串是否只包含不可见字符(空字符、空格、换行符)
 *
 *  @return 字符串是否为不可见
 */
- (BOOL)pl_isInvisibleCharacter {
    return !self || self.length == 0 || [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0;
}

/**
 *  判断字符串是否只包含字母
 *
 *  @return 是否只包含字母
 */
- (BOOL)pl_isLetter {
    return self && self.length > 0 && [self stringByTrimmingCharactersInSet:[NSCharacterSet letterCharacterSet]].length == 0;
}

/**
 *  判断字符串里的字符是否全是大写字母
 *
 *  @return 是否全是大写字母
 */
- (BOOL)pl_isUppercaseLetter {
    return self && self.length > 0 && [self stringByTrimmingCharactersInSet:[NSCharacterSet uppercaseLetterCharacterSet]].length == 0;
}

/**
 *  判断字符串里的字符是否全是小写字母
 *
 *  @return 是否全是小写字母
 */
- (BOOL)pl_isLowercaseLetter {
    return self && self.length > 0 && [self stringByTrimmingCharactersInSet:[NSCharacterSet lowercaseLetterCharacterSet]].length == 0;
}

/**
 判断字符串是不是中文
 
 @return 是否为中文
 */
- (BOOL)pl_isChineseText {
    static NSString *regex = @"^[\u4e00-\u9fa5]$";
    NSPredicate * pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:self];
}

/**
 *  判断字符串中是否存在emoji
 * @return YES(含有表情)
 */
- (BOOL)pl_containEmoji{
    NSString *pattern = @"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    BOOL isMatch = [pred evaluateWithObject:self];
    return isMatch;
}

/**
 *  判断字符串中是否存在emoji
 * @param string 字符串
 * @return YES(含有表情)
 */
+ (BOOL)pl_containEmoji:(NSString *)string {
    __block BOOL returnValue = NO;
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         // surrogate pair
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     returnValue = YES;
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 returnValue = YES;
             }
             
         } else {
             // non surrogate
             if (0x2100 <= hs && hs <= 0x27ff) {
                 returnValue = YES;
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 returnValue = YES;
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 returnValue = YES;
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 returnValue = YES;
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 returnValue = YES;
             }
         }
     }];
    
    return returnValue;
}

@end
